<!-- 项目统计 -->

<template>
  <ContainerLayoutV2 ref="containerLayoutRef" class="project-statistics">
    <template #tables>
      <div class="statistics-container">
        <div class="form-section">
          <el-form :model="formProject" label-width="auto">
            <el-row :gutter="20">
              <el-col :span="4">
                <el-form-item label="项目名称：">
                  <el-select v-model="formProject.name" placeholder="选择" style="width: 100%" @change="handleProjectChange">
                    <el-option v-for="item in optProjectList" :key="item.code" :label="`${item.code}-${item.cname}`" :value="item.id" />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="5">
                <el-form-item label="项目时间：">{{ formProject.time }}</el-form-item>
              </el-col>
              <el-col :span="4">
                <el-form-item label="负责人：">{{ formProject.leader }}</el-form-item>
              </el-col>
              <el-col :span="11">
                <el-form-item label="项目描述：">
                  <div style="width: 100%; text-align: left; line-height: 1.3; padding-top: 6px">
                    <el-text line-clamp="2">
                      {{ formProject.desc }}
                    </el-text>
                  </div>
                </el-form-item>
              </el-col>
            </el-row>
          </el-form>
        </div>
        <el-divider />
        <div class="statistics-section" ref="refStatisticsSection">
          <el-scrollbar :height="scrollbarHeight" always>
            <div class="chart-section" style="position: relative; height: 400px">
              <div class="chart-item">
                <!-- <div class="chart-item-title">
                  <abbr class="main-title" title="项目统计">项目统计</abbr>
                </div> -->
                <v-chart class="chart" :option="option" autoresize ref="refChart1" />
              </div>
              <el-divider direction="vertical" style="height: calc(100% - 85px)" />
              <div class="chart-item">
                <!-- <div class="chart-item-title">
                  <abbr class="main-title" title="卖火柴的小女孩">卖火柴的小女孩</abbr>
                  <div class="sub-title">部门人天占比</div>
                </div> -->
                <v-chart class="chart" :option="option2" autoresize ref="refChart2" />
              </div>
              <div class="date-picker-section">
                <el-date-picker v-model="value1" type="daterange" range-separator="-" :clearable="false" @change="handleDateChange" start-placeholder="开始时间" end-placeholder="结束时间" />
                <el-radio-group style="margin-top: 10px" v-model="radio2" @change="handleRadioChange">
                  <el-radio-button label="一个月" value="1" />
                  <el-radio-button label="三个月" value="2" />
                  <el-radio-button label="半年" value="3" />
                </el-radio-group>
              </div>
            </div>
            <el-divider />
            <TotalProjectProgress />
            <el-divider />

            <div class="table-section">
              <div class="table-toolbar">
                <el-form-item label="">
                  <el-date-picker v-model="value2" type="daterange" range-separator="-" :clearable="false" @change="handleDateChange2" start-placeholder="开始时间" end-placeholder="结束时间" />
                </el-form-item>
              </div>
              <div class="table-container" ref="refTableContainer">
                <el-table ref="dataTable" :data="tableData" :cell-class-name="cellClassName" :span-method="objectSpanMethod" @cell-click="handleTableCellClick" border width="100%" header-cell-class-name="table-header-row" empty-text="没有数据">
                  <el-table-column label="生产环节" min-width="120" fixed>
                    <template #default="scope">
                      {{ scope.row.processName }}
                    </template>
                  </el-table-column>
                  <el-table-column prop="status1" label="状态" min-width="90" fixed />
                  <el-table-column prop="date" label="制作周期" min-width="220" fixed />
                  <el-table-column prop="status2" label="进度情况" min-width="90" fixed />
                  <el-table-column prop="statusName" label="状态" min-width="120" fixed>
                    <template #default="scope"> {{ scope.row.statusName }}({{ scope.row.num }}) </template>
                  </el-table-column>
                  <template v-for="item in tableColumnDate">
                    <el-table-column :prop="item.label" width="70" resizable :label-class-name="getLabelClassName(item.isSameWeek)">
                      <template #header>
                        <div class="table-header-cell">
                          <div>{{ item.label }}</div>
                        </div>
                      </template>
                      <template #default="scope">
                        {{ scope.row[item.columnName] }}
                      </template>
                    </el-table-column>
                  </template>
                </el-table>
              </div>
            </div>
          </el-scrollbar>
        </div>
      </div>
    </template>
  </ContainerLayoutV2>
  <DialogProjectTaskPlanDetail ref="dialogProjectTaskPlanRef" />
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, nextTick } from 'vue'
import ContainerLayoutV2 from '../layout/ContainerLayoutV2.vue'
import TotalProjectProgress from '../components/ProjectStatistics/TotalProjectProgress.vue'
import * as utils from '../utils'
import Api from '../api'
import DialogProjectTaskPlanDetail from '../components/dialog/DialogProjectTaskPlanDetail.vue'

const dialogProjectTaskPlanRef = ref<InstanceType<typeof DialogProjectTaskPlanDetail>>()
const refStatisticsSection = ref()
const scrollbarHeight = ref(400)
const refChart1 = ref()
const refChart2 = ref()

const value1 = ref<Date[] | null>([])
const value2 = ref<Date[] | null>([])
const radio2 = ref('1')
const refTableContainer = ref()
const formProject = reactive({
  name: null,
  desc: '',
  time: '',
  leader: '',
})
// const calendarValue = ref(new Date())

const option = ref<any>({})
const option2 = ref<any>({})
const tableHeight = ref(400)
const tableData = ref<any[]>([])
const tableColumnDate = ref<any[]>([])
// 项目列表
const optProjectList = ref<any[]>([])
const weeks = ref()

/**
 * 处理单选按钮变化的事件处理函数
 *
 * 当单选按钮状态发生变化时，调用该函数
 * 该函数会调用 setPieChart 和 setPieChart2 两个函数
 */
const handleRadioChange = () => {
  let ago = 1
  if (radio2.value === '1') {
    ago = 1
  } else if (radio2.value === '2') {
    ago = 3
  } else if (radio2.value === '3') {
    ago = 6
  }

  const start1 = utils.getMonthsAgo(new Date(), ago)
  const end1 = new Date()
  value1.value = [start1, end1]
  nextTick(() => {
    setPieChart()
    setPieChart2()
  })
}

/**
 * 处理日期变化事件（饼图）
 *
 * 当日期变化时，调用此方法以更新图表数据。
 */
const handleDateChange = () => {
  radio2.value = '0'

  setPieChart()
  setPieChart2()
}

/**
 * 处理日期变化事件（表格）
 */
const handleDateChange2 = () => {
  setTableColumnDate()
}

const getLabelClassName = (isSameWeek: boolean) => {
  return isSameWeek ? 'is-same-week' : ''
}

const cellClassName = ({ row, column }: { row: any; column: any; rowIndex: number; columnIndex: number }) => {
  let className = row[column.property + '|className']
  return className
}

/**
 * 设置表格列日期
 *
 * @returns 无返回值
 */
const setTableColumnDate = () => {
  if (value2.value === null) return

  // 创建一个日期对象，表示起始日期
  const start = value2.value[0]

  // 创建一个日期对象，表示当前日期
  const end = value2.value[1]
  // 调用utils.getWeeksBetweenDates方法，计算起始日期和当前日期之间的周数，并赋值给weeks.value
  weeks.value = utils.getWeeksBetweenDates(start, end)

  // 初始化tableColumnDate.value，并遍历weeks.value数组
  tableColumnDate.value = [
    ...weeks.value.map((e: any) => {
      // 将每周的开始日期格式化为'yyyy-MM-dd'格式
      const start = utils.formatDate(e.start, 'yyyy-MM-dd')
      // console.log('start', start)
      // 将每周的结束日期格式化为'yyyy-MM-dd'格式
      const end = utils.formatDate(e.end, 'yyyy-MM-dd')
      // 将每周的开始日期格式化为'yyyy'格式
      const startYear = utils.formatDate(e.start, 'yyyy')
      // 将每周的结束日期格式化为'yyyy'格式
      const endYear = utils.formatDate(e.end, 'yyyy')
      // 将每周的开始日期格式化为'MM-dd'格式
      const startDay = utils.formatDate(e.start, 'MM-dd')
      // 将每周的结束日期格式化为'MM-dd'格式
      const endDay = utils.formatDate(e.end, 'MM-dd')
      // 判断当前日期是否与开始日期在同一周
      const isSameWeek = utils.isSameWeek(start, Date.now())
      // 返回一个对象，包含是否是同一周、标签、列名、开始日期、结束日期、开始年月日、结束年月日等信息
      return { isSameWeek, label: start, columnName: `${start} - ${end}`, start, end, startDay, endDay, startYear, endYear }
    }),
  ]
}

/**
 * 将 list2 数组转换为 list3 数组
 *
 * @param list2 需要转换的源数组
 * @returns 转换后的目标数组
 */
const transformList2To3 = (list2: any[]) => {
  const list3: any[] = []

  // 遍历 list2 中的每个项目
  list2.forEach((item) => {
    // 创建基础对象
    const baseObj = {
      date: item.date,
      status1: item.status1,
      processName: item.processName,
      status2: item.status2,
    }
    // 创建计划数量对象
    const planObj: any = { ...baseObj, statusName: '制作计划', num: item.planNum }
    // 创建完成数量对象
    const finishObj: any = { ...baseObj, statusName: '实际进度', num: item.finishNum }

    // 处理 list 数组中的数据
    item.list.forEach((wd: any) => {
      // console.log('wd', wd)

      const weekRange = `${wd.weekStartDate} - ${wd.weekEndDate}`

      // 填充计划数量
      planObj[weekRange] = wd.weekPlanNum
      planObj[wd.weekStartDate + '|id'] = wd.id
      // 填充完成数量
      finishObj[weekRange] = wd.weekFinishNum
      finishObj[wd.weekStartDate + '|id'] = wd.id

      let className = ''
      if (item.status2 == '滞后') {
        className = 'danger'
      } else if (item.status2 == '超前') {
        className = 'success'
      } else {
        className = 'primary'
      }
      if (wd.weekPlanNum != null) {
        planObj[wd.weekStartDate + '|className'] = 'warning'
      }
      if (wd.weekFinishNum != null) {
        finishObj[wd.weekStartDate + '|className'] = className
      }
    })

    // 将两个对象添加到结果数组
    list3.push(planObj, finishObj)
  })

  return list3
}

/**
 * 处理表格单元格点击事件
 *
 * @param row 被点击的行数据
 * @param column 被点击的列数据
 */
const handleTableCellClick = async (row: any, column: any) => {
  // console.log('row', row[column.property + '|id'])
  if (row[column.property + '|id']) {
    const res = await Api.InformationRequirement.getDetailById(row[column.property + '|id'])
    if (res.code == 200) {
      console.log('res', res.data)
      dialogProjectTaskPlanRef.value?.openDialog(res.data)
    }
  }
}

const setTableData = async () => {
  const searchDate = utils.getWeekEnd(new Date())
  const { rows } = await Api.InformationRequirement.getListAll({
    projectId: formProject.name,
    weekEndDate: utils.formatDate(searchDate, 'yyyy-MM-dd'),
  })
  // 使用示例
  const list3 = transformList2To3(rows)
  // console.log('list3', list3)
  tableData.value = list3
}
/**
 * 设置饼图选项
 *
 * @returns 无返回值
 */
const setPieChartOptions = (title: string, data: any[], subtext: string) => {
  return {
    title: {
      // show: false,
      text: title,
      subtext,
      left: 'center',
      top: '52%',
      textStyle: {
        fontSize: 20,
        color: '#333',
      },
      z: 1000,
    },
    tooltip: {
      trigger: 'item',
      formatter: (params: any) => {
        return `
      <div style="display: flex; align-items: center">
        <span style="
          display: inline-block;
          width: 10px;
          height: 10px;
          background: ${params.color};
          margin-right: 5px;
          border-radius: 50%;
        "></span>
        ${params.name} (${params.percent}%，${params.value}人/天)
      </div>
    `
      },
    },
    legend: {
      show: false,
      orient: 'vertical',
      left: 'left',
    },
    series: [
      {
        name: '',
        type: 'pie',
        radius: ['50%', '75%'],
        center: ['50%', '55%'],
        selectedOffset: 12,
        selectedMode: 'single',
        data,
        emphasis: {
          itemStyle: {
            shadowBlur: 10,
            shadowOffsetX: 0,
            shadowColor: 'rgba(0, 0, 0, 0.5)',
          },
        },
      },
    ],
  }
}
/**
 * 设置图表配置并生成饼图（按时间查询全项目饼状图数据）
 *
 * @returns 无返回值
 */
const setPieChart = async () => {
  option.value = {}
  if (!value1.value) {
    return
  }
  const startTimelogDate = utils.formatDate(value1.value[0], 'yyyy-MM-dd')
  const endTimelogDate = utils.formatDate(value1.value[1], 'yyyy-MM-dd')

  const { rows } = await Api.Timtlogs.getListGroup(startTimelogDate, endTimelogDate)
  // console.log('rows', rows)
  const projectName = optProjectList.value.find((item) => item.id == Number(formProject.name))?.cname
  // 获取项目列表
  const data: any[] = []
  if (formProject.name) {
    rows.forEach((item: any) => {
      data.push({
        value: item.durationTime,
        name: item.projectName,
        selected: formProject.name ? item.projectName == projectName : false,
      })
    })
  }
  option.value = setPieChartOptions('项目统计', data, '')
}
/**
 * 项目部门人天占比
 * 设置图表配置并生成饼图 （按项目id查各部门饼状图数据）
 *
 * @returns 返回异步操作结果
 */
const setPieChart2 = async () => {
  option2.value = {}
  if (!value1.value) {
    return
  }
  const startTimelogDate = utils.formatDate(value1.value[0], 'yyyy-MM-dd')
  const endTimelogDate = utils.formatDate(value1.value[1], 'yyyy-MM-dd')

  // 获取项目列表
  const data: any[] = []
  let cname = ''
  if (formProject.name) {
    const { rows } = await Api.Timtlogs.getListGroupDept(startTimelogDate, endTimelogDate, formProject.name)
    rows.forEach((item: any) => {
      data.push({
        value: item.durationTime,
        name: item.deptName,
        selected: false,
      })
    })
    cname = optProjectList.value.find((item) => item.id == formProject.name)?.cname
  }

  option2.value = setPieChartOptions(cname, data, '部门人天占比')
}
/**
 * 根据行索引和列索引返回表格单元格的合并策略
 *
 * @param param 参数对象，包含行索引和列索引
 * @param param.rowIndex 行索引
 * @param param.columnIndex 列索引
 * @returns 返回单元格的合并策略，包括行合并数和列合并数
 */
const objectSpanMethod = ({ rowIndex, columnIndex }: any) => {
  if (columnIndex <= 3) {
    if (rowIndex % 2 === 0) {
      return {
        rowspan: 2,
        colspan: 1,
      }
    } else {
      return {
        rowspan: 0,
        colspan: 0,
      }
    }
  }
}

/**
 * 处理项目变化的事件处理函数
 *
 * @param val 传入的项目值，可以是任何类型
 */
const handleProjectChange = (val: any) => {
  formProject.leader = ''
  formProject.time = ''
  formProject.desc = ''
  const item: any = optProjectList.value.find((e: any) => e.id == val)
  if (item) {
    formProject.leader = item.producer
    formProject.time = `${item.startTime || '未知'} —— ${item.endTime || '至今'}`
    formProject.desc = item.remark
  }

  // value1.value = utils.getDateRangeByDate(utils.shortcutsType.本周, new Date())

  const currentDate = new Date()
  const year = currentDate.getFullYear()
  const month = currentDate.getMonth()

  // 创建一个日期对象，表示起始日期
  const start = new Date(year, month - 2, 1)
  // 创建一个日期对象，表示当前日期
  const end = new Date(year, month + 3, 0)
  if (!value1.value || value1.value.length == 0) {
    const start1 = utils.getMonthsAgo(new Date(), 1)
    const end1 = new Date()
    value1.value = [start1, end1]
  }
  value2.value = [start, end]

  setTableColumnDate()
  setPieChart()
  setPieChart2()
  setTableData()
}
const setTableHeight = () => {
  tableHeight.value = 0
  nextTick(() => {
    if (refStatisticsSection.value) {
      scrollbarHeight.value = refStatisticsSection.value.offsetHeight
    }
    if (refTableContainer.value) {
      tableHeight.value = refTableContainer.value.offsetHeight
    }
  })
}

const getProjectList = async () => {
  const res = await Api.Projects.getProjectListByParams({
    projectStatus: 1,
    pageSize: 99999,
    display: 0,
  })
  optProjectList.value = res.rows || []
}

onMounted(async () => {
  getProjectList()
  setTableHeight()
})
</script>

<style lang="scss" scoped>
.is-same-week {
  background-color: aqua;
}
.statistics-container {
  height: 100%;
  display: flex;
  flex-direction: column;
  .date-picker-section {
    position: absolute;
    left: 50%;
    top: 0;
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
  }
  .statistics-section {
    // flex: 1;
    transition: all 0.2s ease-in-out;
    flex: 1;
    overflow-x: hidden;
  }

  .statistics-section {
    .left-group,
    .chart-section {
      transition: all 0.2s ease-in-out;
    }
    .left-group {
      // width: 40%;
    }
    .chart-section {
      // width: 60%;
      display: flex;
      align-items: flex-end;
      .chart-item {
        position: relative;
        width: 50%;
        height: 100%;
        .chart-item-title {
          position: absolute;
          top: 210px;
          left: 50%;
          width: auto;
          height: auto;
          line-height: 1;
          z-index: 99999;
          transform: translate(-50%, 0px);
          cursor: default;
          .main-title {
            font-size: 20px;
            font-weight: bold;
            color: #333;
            text-decoration: none;
            display: block;
          }
          .sub-title {
            font-size: 12px;
            color: #666;
            margin-top: 11px;
          }
        }
      }
    }
    &.view-1-1 {
      .left-group {
        width: 40%;
      }
      .chart-section {
        width: 60%;
      }
    }
    &.view-2-1 {
      .left-group {
        width: 70%;
      }
      .chart-section {
        width: 30%;
      }
    }
    &.view-1-2 {
      .left-group {
        width: 30%;
      }
      .chart-section {
        width: 70%;
      }
    }
  }
  .table-section {
    // flex: 1;
    transition: all 0.2s ease-in-out;
    display: flex;
    flex-direction: column;

    .table-toolbar {
      display: flex;
      justify-self: start;
      flex-wrap: wrap;
      padding-bottom: 10px;
    }
    .table-container {
      flex: 1;
    }
  }
  .form-section {
  }
  .left-group {
    display: flex;
    flex-direction: column;
  }
  .calendar-section {
    flex: 1;
    position: relative;
    .calendar-container {
      position: absolute;
      left: 0;
      top: 0%;
      width: 100%;
      height: 100%;
      overflow: hidden;
    }
  }
  &.view-1-1 {
    .statistics-section {
      height: 50%;
    }
    .table-section {
      height: 50%;
    }
  }
  &.view-2-1 {
    .statistics-section {
      height: 67%;
    }
    .table-section {
      height: 33%;
    }
  }
  &.view-1-2 {
    .statistics-section {
      height: 33%;
    }
    .table-section {
      height: 67%;
    }
  }
}
</style>
